home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Python 1.1 / Demo / tkinter / guido / tkman.py < prev    next >
Encoding:
Python Source  |  1994-10-11  |  6.3 KB  |  243 lines  |  [TEXT/R*ch]

  1. #! /usr/local/bin/python
  2.  
  3. # Tk man page browser -- currently only shows the Tcl/Tk man pages
  4.  
  5. import sys
  6. import os
  7. import string
  8. import regex
  9. from Tkinter import *
  10.  
  11. import addpack
  12. addpack.addpack('/ufs/guido/src/python/Demo/guido/tkinter')
  13. from ManPage import ManPage
  14.  
  15. MANNDIR = '/usr/local/man/mann'
  16. MAN3DIR = '/usr/local/man/man3'
  17.  
  18. def listmanpages(mandir):
  19.     files = os.listdir(mandir)
  20.     names = []
  21.     for file in files:
  22.         if file[-2:-1] == '.' and  (file[-1] in 'ln123456789'):
  23.             names.append(file[:-2])
  24.     names.sort()
  25.     return names
  26.  
  27. class SelectionBox:
  28.  
  29.     def __init__(self, master=None):
  30.         self.choices = []
  31.  
  32.         self.frame = Frame(master, {
  33.             'name': 'frame',
  34.             Pack: {'expand': 1, 'fill': 'both'}})
  35.         self.master = self.frame.master
  36.         self.subframe = Frame(self.frame, {
  37.             'name': 'subframe',
  38.             Pack: {'expand': 0, 'fill': 'both'}})
  39.         self.leftsubframe = Frame(self.subframe, {
  40.             'name': 'leftsubframe',
  41.             Pack: {'side': 'left', 'expand': 1, 'fill': 'both'}})
  42.         self.rightsubframe = Frame(self.subframe, {
  43.             'name': 'rightsubframe',
  44.             Pack: {'side': 'right', 'expand': 1, 'fill': 'both'}})
  45.         self.chaptervar = StringVar(master)
  46.         self.chapter = Menubutton(self.rightsubframe,
  47.                       {'name': 'chapter',
  48.                        'text': 'Directory',
  49.                        'relief': 'raised', 'bd': 2,
  50.                        Pack: {'side': 'top'}})
  51.         self.chaptermenu = Menu(self.chapter, {'name': 'chaptermenu'})
  52.         self.chaptermenu.add_radiobutton({'label': 'C functions',
  53.                           'value': MAN3DIR,
  54.                           'variable': self.chaptervar,
  55.                           'command': self.newchapter})
  56.         self.chaptermenu.add_radiobutton({'label': 'Tcl/Tk functions',
  57.                           'value': MANNDIR,
  58.                           'variable': self.chaptervar,
  59.                           'command': self.newchapter})
  60.         self.chapter['menu'] = self.chaptermenu
  61.         self.listbox = Listbox(self.rightsubframe,
  62.                        {'name': 'listbox',
  63.                     'relief': 'sunken', 'bd': 2,
  64.                     'geometry': '20x5',
  65.                     Pack: {'expand': 1, 'fill': 'both'}})
  66.         self.l1 = Button(self.leftsubframe,
  67.                 {'name': 'l1',
  68.                  'text': 'Display manual page named:',
  69.                  'command': self.entry_cb,
  70.                  Pack: {'side': 'top'}})
  71.         self.entry = Entry(self.leftsubframe,
  72.                    {'name': 'entry',
  73.                     'relief': 'sunken', 'bd': 2,
  74.                     'width': 20,
  75.                     Pack: {'side': 'top',
  76.                        'expand': 0, 'fill': 'x'}})
  77.         self.l2frame = Frame(self.leftsubframe,
  78.                      {'name': 'l2frame',
  79.                       Pack: {'expand': 0, 'fill': 'none'}})
  80.         self.l2 = Button(self.l2frame,
  81.                 {'name': 'l2',
  82.                  'text': 'Search regexp:',
  83.                  'command': self.search_cb,
  84.                  Pack: {'side': 'left'}})
  85.         self.casesense = Checkbutton(self.l2frame,
  86.                          {'name': 'casesense',
  87.                           'text': 'Case sensitive',
  88.                           'variable': 'casesense',
  89.                           'relief': 'flat',
  90.                           Pack: {'side': 'left'}})
  91.         self.search = Entry(self.leftsubframe,
  92.                    {'name': 'search',
  93.                     'relief': 'sunken', 'bd': 2,
  94.                     'width': 20,
  95.                     Pack: {'side': 'top',
  96.                        'expand': 0, 'fill': 'x'}})
  97.         self.title = Label(self.leftsubframe,
  98.                    {'name': 'title',
  99.                     'text': '(none)',
  100.                     Pack: {'side': 'bottom'}})
  101.         self.text = ManPage(self.frame,
  102.                      {'name': 'text',
  103.                       'relief': 'sunken', 'bd': 2,
  104.                       'wrap': 'none', 'width': 72,
  105.                       Pack: {'expand': 1, 'fill': 'both'}})
  106.  
  107.         self.entry.bind('<Return>', self.entry_cb)
  108.         self.search.bind('<Return>', self.search_cb)
  109.         self.listbox.bind('<Double-1>', self.listbox_cb)
  110.  
  111.         self.entry.bind('<Tab>', self.entry_tab)
  112.         self.search.bind('<Tab>', self.search_tab)
  113.         self.text.bind('<Tab>', self.text_tab)
  114.  
  115.         self.entry.focus_set()
  116.  
  117.         self.chaptervar.set(MANNDIR)
  118.         self.newchapter()
  119.  
  120.     def newchapter(self):
  121.         mandir = self.chaptervar.get()
  122.         self.choices = []
  123.         self.addlist(listmanpages(mandir))
  124.  
  125.     def addchoice(self, choice):
  126.         if choice not in self.choices:
  127.             self.choices.append(choice)
  128.             self.choices.sort()
  129.         self.update()
  130.  
  131.     def addlist(self, list):
  132.         self.choices[len(self.choices):] = list
  133.         self.choices.sort()
  134.         self.update()
  135.  
  136.     def entry_cb(self, *e):
  137.         self.update()
  138.  
  139.     def listbox_cb(self, e):
  140.         selection = self.listbox.curselection()
  141.         if selection and len(selection) == 1:
  142.             name = self.listbox.get(selection[0])
  143.             self.show_page(name)
  144.  
  145.     def search_cb(self, *e):
  146.         self.search_string(self.search.get())
  147.  
  148.     def entry_tab(self, e):
  149.         self.search.focus_set()
  150.  
  151.     def search_tab(self, e):
  152.         self.entry.focus_set()
  153.  
  154.     def text_tab(self, e):
  155.         self.entry.focus_set()
  156.  
  157.     def updatelist(self):
  158.         key = self.entry.get()
  159.         ok = filter(lambda name, key=key, n=len(key): name[:n]==key,
  160.              self.choices)
  161.         self.listbox.delete(0, AtEnd())
  162.         exactmatch = 0
  163.         for item in ok:
  164.             if item == key: exactmatch = 1
  165.             self.listbox.insert(AtEnd(), item)
  166.         if exactmatch:
  167.             return key
  168.         elif self.listbox.size() == 1:
  169.             return self.listbox.get(0)
  170.         # Else return None, meaning not a unique selection
  171.  
  172.     def update(self):
  173.         name = self.updatelist()
  174.         if name:
  175.             self.show_page(name)
  176.             self.entry.delete(0, AtEnd())
  177.             self.updatelist()
  178.  
  179.     def show_page(self, name):
  180.         file = '%s/%s.?' % (self.chaptervar.get(), name)
  181.         fp = os.popen('nroff -man %s | ul -i' % file, 'r')
  182.         self.text.kill()
  183.         self.title['text'] = name
  184.         self.text.parsefile(fp)
  185.  
  186.     def search_string(self, search):
  187.         if not search:
  188.             print 'Empty search string'
  189.             return
  190.         if self.frame.tk.getvar('casesense') != '1':
  191.             map = regex.casefold
  192.         else:
  193.             map = None
  194.         try:
  195.             if map:
  196.                 prog = regex.compile(search, map)
  197.             else:
  198.                 prog = regex.compile(search)
  199.         except regex.error, msg:
  200.             print 'Regex error:', msg
  201.             return
  202.         here = self.text.index(AtInsert())
  203.         lineno = string.atoi(here[:string.find(here, '.')])
  204.         end = self.text.index(AtEnd())
  205.         endlineno = string.atoi(end[:string.find(end, '.')])
  206.         wraplineno = lineno
  207.         while 1:
  208.             lineno = lineno + 1
  209.             if lineno > endlineno:
  210.                 if wraplineno <= 0:
  211.                     break
  212.                 endlineno = wraplineno
  213.                 lineno = 0
  214.                 wraplineno = 0
  215.             line = self.text.get('%d.0 linestart' % lineno,
  216.                          '%d.0 lineend' % lineno)
  217.             i = prog.search(line)
  218.             if i >= 0:
  219.                 n = max(1, len(prog.group(0)))
  220.                 try:
  221.                     self.text.tag_remove('sel',
  222.                                  AtSelFirst(),
  223.                                  AtSelLast())
  224.                 except TclError:
  225.                     pass
  226.                 self.text.tag_add('sel',
  227.                           '%d.%d' % (lineno, i),
  228.                           '%d.%d' % (lineno, i+n))
  229.                 self.text.mark_set(AtInsert(),
  230.                            '%d.%d' % (lineno, i))
  231.                 self.text.yview_pickplace(AtInsert())
  232.                 break
  233.  
  234. def main():
  235.     root = Tk()
  236.     sb = SelectionBox(root)
  237.     if sys.argv[1:]:
  238.         sb.show_page(sys.argv[1])
  239.     root.minsize(1, 1)
  240.     root.mainloop()
  241.  
  242. main()
  243.